#pragma once

#include <signal.h>
#include <unistd.h>
#include <cstdlib>
#include <cassert>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define DEV "/dev/null"

void daemonSelf(const char *currPath = nullptr)
{
    // 1. 先把异常的信号忽略掉, 防止其他的进程影响服务器的调用进程
    signal(SIGPIPE, SIG_IGN);
    // 2. 使用setsid使自己成为组长
    if(fork() > 0) exit(0);
    // 子进程 (守护进程---精灵进程)
    pid_t n = setsid();
    assert(n != -1);
    // 3. 守护进程脱离终端, 一旦运行起来就不需要与其他文件(广义上的)打交道, 可以关闭或重定向默认打开的文件
    int fd = open(DEV, O_RDWR);
    if(fd > 0)
    {
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);

        close(fd);
    }
    else
    {
        close(0);
        close(1);
        close(2);
    }
    // 4. (可选)使进程的执行路径发生改变
    if(!currPath) chdir(currPath);
}